// SPDX-FileCopyrightText: Copyright 2025-2025 深圳市同心圆网络有限公司
// SPDX-License-Identifier: Apache-2.0

package roadmap_rag_api_serv

import (
	"context"
	"math"
	"time"

	"gitcode.com/lvupclub/lvup-api/dao"
	"gitcode.com/lvupclub/lvup-api/dao/roadmap_dao"
	"gitcode.com/lvupclub/lvup-api/dao/user_dao"
	"gitcode.com/lvupclub/proto-gen-go.git/src/roadmap_rag_api"
	"github.com/google/uuid"
)

func (apiImpl *RoadmapRagApiImpl) SendMessage(req *roadmap_rag_api.SendMessageRequest, s roadmap_rag_api.RoadmapRagApi_SendMessageServer) error {
	ctx := s.Context()

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		s.Send(&roadmap_rag_api.SendMessageResponse{
			Code:   roadmap_rag_api.SendMessageResponse_CODE_WRONG_SESSION,
			ErrMsg: "会话不存在",
		})
		return nil

	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		s.Send((&roadmap_rag_api.SendMessageResponse{
			Code:   roadmap_rag_api.SendMessageResponse_CODE_NO_ROADMAP,
			ErrMsg: "成长路线图不存在",
		}))
		return nil
	}
	if roadmapItem.OwnerUserId != sessItem.UserId {
		exist, err := roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, sessItem.UserId)
		if err != nil {
			return err
		}
		if !exist {
			s.Send((&roadmap_rag_api.SendMessageResponse{
				Code:   roadmap_rag_api.SendMessageResponse_CODE_NO_PERMISSION,
				ErrMsg: "没有权限",
			}))
			return nil
		}
	}

	ragConfigItem, err := roadmap_dao.RagConfigDao.Get(ctx, req.RoadmapId, req.RagConfigId)
	if err != nil {
		s.Send((&roadmap_rag_api.SendMessageResponse{
			Code:   roadmap_rag_api.SendMessageResponse_CODE_NO_CONFIG,
			ErrMsg: "知识库配置不存在",
		}))
		return nil
	}
	//写入提问消息
	userMessageId := uuid.NewString()
	err = roadmap_dao.ChatMessageDao.Insert(ctx, &roadmap_dao.ChatMessageDbItem{
		MessageId:   userMessageId,
		RoadmapId:   req.RoadmapId,
		RagConfigId: req.RagConfigId,
		ChatRole:    roadmap_rag_api.CHAT_ROLE_TYPE_CHAT_ROLE_USER,
		Content:     req.Content,
		TimeStamp:   time.Now().UnixMilli(),
		OwnerUserId: sessItem.UserId,
	})
	if err != nil {
		return err
	}
	//处理消息
	var answerContent string
	assistantTimeStamp := time.Now().UnixMilli()
	assistantMessageId := uuid.NewString()
	if ragConfigItem.BasicConfig.ProviderType == roadmap_rag_api.RAG_PROVIDER_TYPE_RAG_PROVIDER_YD_QANYTHING {
		answerContent, err = apiImpl.processQAnything(s, ragConfigItem, sessItem.UserId, assistantMessageId, assistantTimeStamp)
		if err != nil {
			return err
		}
	} else if ragConfigItem.BasicConfig.ProviderType == roadmap_rag_api.RAG_PROVIDER_TYPE_RAG_PROVIDER_FASTGPT {
		answerContent, err = apiImpl.processFastGpt(s, ragConfigItem, sessItem.UserId, assistantMessageId, assistantTimeStamp)
		if err != nil {
			return err
		}
	}
	//写入结果
	err = roadmap_dao.ChatMessageDao.Insert(ctx, &roadmap_dao.ChatMessageDbItem{
		MessageId:   assistantMessageId,
		RoadmapId:   req.RoadmapId,
		RagConfigId: req.RagConfigId,
		ChatRole:    roadmap_rag_api.CHAT_ROLE_TYPE_CHAT_ROLE_ASSISTANT,
		Content:     answerContent,
		TimeStamp:   time.Now().UnixMilli(),
		OwnerUserId: sessItem.UserId,
	})
	if err != nil {
		return err
	}

	//返回结果
	s.Send((&roadmap_rag_api.SendMessageResponse{
		Code:                 roadmap_rag_api.SendMessageResponse_CODE_OK,
		UserMessageId:        userMessageId,
		AssistantTimeStamp:   assistantTimeStamp,
		AssistantMessageId:   assistantMessageId,
		AssistantContentPart: "",
	}))
	return nil
}

func (apiImpl *RoadmapRagApiImpl) ListMessage(ctx context.Context, req *roadmap_rag_api.ListMessageRequest) (*roadmap_rag_api.ListMessageResponse, error) {
	emptyList := []*roadmap_rag_api.ChatMessage{}

	sessItem, ok := dao.CacheDao.GetSession(ctx, req.SessionId)
	if !ok {
		return &roadmap_rag_api.ListMessageResponse{
			Code:        roadmap_rag_api.ListMessageResponse_CODE_WRONG_SESSION,
			ErrMsg:      "会话不存在",
			MessageList: emptyList,
		}, nil
	}
	roadmapItem, err := roadmap_dao.RoadmapInfoDao.Get(ctx, req.RoadmapId)
	if err != nil {
		return &roadmap_rag_api.ListMessageResponse{
			Code:        roadmap_rag_api.ListMessageResponse_CODE_NO_ROADMAP,
			ErrMsg:      "会话不存在",
			MessageList: emptyList,
		}, nil
	}
	exist, err := roadmap_dao.RagConfigDao.Exist(ctx, req.RoadmapId, req.RagConfigId)
	if err != nil {
		return nil, err
	}
	if !exist {
		return &roadmap_rag_api.ListMessageResponse{
			Code:        roadmap_rag_api.ListMessageResponse_CODE_NO_CONFIG,
			ErrMsg:      "知识库配置不存在",
			MessageList: emptyList,
		}, nil
	}
	if roadmapItem.OwnerUserId == sessItem.UserId {
		if sessItem.UserId != req.TargetMemberUserId {
			exist, err = roadmap_dao.RoadmapMemberDao.Exist(ctx, req.RoadmapId, req.TargetMemberUserId)
			if err != nil {
				return nil, err
			}
			if !exist {
				return &roadmap_rag_api.ListMessageResponse{
					Code:        roadmap_rag_api.ListMessageResponse_CODE_NO_PERMISSION,
					ErrMsg:      "没有权限",
					MessageList: emptyList,
				}, nil
			}
		}
	} else {
		if sessItem.UserId != req.TargetMemberUserId {
			return &roadmap_rag_api.ListMessageResponse{
				Code:        roadmap_rag_api.ListMessageResponse_CODE_NO_PERMISSION,
				ErrMsg:      "没有权限",
				MessageList: emptyList,
			}, nil
		}
	}

	var cmpTimeStamp int64

	if req.RefMessageId != "" {
		refMsgItem, err := roadmap_dao.ChatMessageDao.Get(ctx, req.RoadmapId, req.RagConfigId, req.TargetMemberUserId, req.RefMessageId)
		if err != nil {
			return nil, err
		}
		cmpTimeStamp = refMsgItem.TimeStamp
	} else {
		cmpTimeStamp = math.MaxInt64
	}

	userItemList, err := user_dao.UserInfoDao.ListById(ctx, []string{req.TargetMemberUserId})
	if err != nil {
		return nil, err
	}

	msgItemList, err := roadmap_dao.ChatMessageDao.List(ctx, req.RoadmapId, req.RagConfigId, req.TargetMemberUserId, cmpTimeStamp, req.ListType, int64(req.Limit))
	if err != nil {
		return nil, err
	}

	msgList := []*roadmap_rag_api.ChatMessage{}

	for _, msgItem := range msgItemList {
		msg := msgItem.ToChatMessage()
		if len(userItemList) > 0 {
			msg.OwnerDisplayName = userItemList[0].BasicInfo.DisplayName
			msg.OwnerLogoUri = userItemList[0].BasicInfo.LogoUri
		}
		msgList = append(msgList, msg)
	}

	return &roadmap_rag_api.ListMessageResponse{
		Code:        roadmap_rag_api.ListMessageResponse_CODE_OK,
		MessageList: msgList,
	}, nil
}
